package toy.keli.edic.ui.main.extend

import android.view.View
import android.view.ViewTreeObserver
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusState
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.Request
import toy.keli.edic.data.UserStatus
import toy.keli.edic.ui.main.components.Display
import toy.keli.edic.ui.main.components.Display.mt
import toy.keli.edic.ui.main.components.Display.px2dp
import toy.keli.edic.util.ActivityRun

@Composable
fun MText(text: String,
          modifier: Modifier = Modifier,
          color: Color = Color.Unspecified,
          fontSize: TextUnit = TextUnit.Unspecified,
          textAlign: TextAlign? = null,
          style: TextStyle = LocalTextStyle.current
          ){
    val textNew = if(text.endsWith(":")) mt(text.trim(':')) else mt(text)
    Text(textNew,modifier,color,fontSize=fontSize,style=style,textAlign=textAlign)
}

@Composable
fun HtmlView(source:String,height:Float=1f,linkBlockOpen:Boolean=true){
    val p = Display.getScreenSize()
    AndroidView(
        modifier = Modifier
            .width(px2dp(p.x))
            .height(px2dp(p.y) * height),
        factory = { context ->
            WebView(context).apply {
                setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)
                setHorizontalScrollBarEnabled(false)
                getSettings().apply {
                    if(!linkBlockOpen) {
                        webViewClient = object : WebViewClient() {
                            //重写shouldOverrideUrlLoading方法，使点击链接后不使用其他的浏览器打开。
                            override fun shouldOverrideUrlLoading(
                                view: WebView,
                                url: String
                            ): Boolean {
                                if (url.matches(Regex(".+\\.htm*"))) {
                                    view.loadUrl(url)
                                    //如果不需要其他对点击链接事件的处理返回true，否则返回false
                                    return true
                                } else {
                                    val request = Request.Builder().url(url).build()
                                    bgRun {
                                        OkHttpClient().newCall(request).execute().use { response ->
                                            var textData = response.body?.string() ?: ""
                                            MainScope().launch {
                                                view.loadData(textData, "text/html", "UTF-8")
                                                setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)
                                                setHorizontalScrollBarEnabled(false)
                                            }
                                        }
                                    }
                                    return true
                                }
                            }
                        }
                        javaScriptEnabled = true
                    }
//                    setUseWideViewPort(true)
//                    setLoadWithOverviewMode(true)
                }
                loadData(source, "text/html", "UTF-8")
            }
        }
    )
}

// 自定义修饰符：确保组件至少是方形（宽度≥高度）
fun Modifier.squareMinSize() = layout { measurable, constraints ->
    val placeable = measurable.measure(constraints)

    // 计算最小宽度（至少等于高度）
    val minWidth = placeable.height.coerceAtLeast(constraints.minWidth)

    // 应用新的宽度约束
    val newConstraints = constraints.copy(
        minWidth = minWidth,
        maxWidth = Math.max(constraints.maxWidth,minWidth)
    )

    val finalPlaceable = measurable.measure(newConstraints)

    // 放置组件
    layout(finalPlaceable.width, finalPlaceable.height) {
        finalPlaceable.place(0, 0)
    }
}
/**
 * 修正版：计算LazyList的滚动百分比（不依赖averageItemSize）
 * @return 滚动百分比（0.0 ~ 100.0），不可滚动时返回0.0
 */
@Composable
fun LazyListState.calculateScrollPercentage(): Double {
    return remember(this) {
        derivedStateOf {
            val layoutInfo = this.layoutInfo
            val visibleItems =  layoutInfo.visibleItemsInfo
            if (visibleItems.isEmpty()) return@derivedStateOf 0.0

            // 1. 计算总可滚动距离 = 列表总高度 - 可见区域高度
            val totalContentHeight = layoutInfo.totalItemsCount // 所有项的总高度（像素）
            val viewportHeight = layoutInfo.viewportSize.height // 可见区域高度（像素）
            val totalScrollableDistance = totalContentHeight - viewportHeight
            if (totalScrollableDistance <= 0) return@derivedStateOf 0.0 // 内容不足一屏

            // 2. 计算当前已滚动的总距离
            val firstVisibleIndex = this.firstVisibleItemIndex
            val firstVisibleOffset = this.firstVisibleItemScrollOffset // 当前项已滚动出屏幕的高度

            // 2.1 计算所有“完全滚动出屏幕的项”的总高度
            var fullScrolledHeight = 0
            // 遍历可见项，累加“索引小于当前第一个可见项”的项高度（这些项已完全滚出屏幕）
            for (item in visibleItems) {
                if (item.index < firstVisibleIndex) {
                    fullScrolledHeight += item.size
                }
            }

            // 2.2 已滚动总距离 = 完全滚出的项总高度 + 当前项已滚出的高度
            val currentScrollOffset = fullScrolledHeight + firstVisibleOffset

            // 3. 计算百分比并限制范围
            val percentage = (currentScrollOffset.toDouble() / totalScrollableDistance) * 100
            percentage.coerceIn(0.0, 100.0)
        }
    }.value
}


// 自定义修饰符：根据状态控制是否允许滚动
fun Modifier.scrollEnabled(enabled: Boolean): Modifier {
    return if (!enabled) {
        // 禁用滚动：拦截所有滚动事件
        this.nestedScroll(object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                return available // 消耗所有滚动距离，阻止滚动
            }
        })
    } else {
        // 启用滚动：不做拦截
        this
    }
}

/**
 * 兼容键盘收起算作焦点修改触发事件
 */
fun Modifier.onInputFocusChanged(run:FocusState.(isFocused:Boolean)->Unit): Modifier {
    return this.onFocusChanged {
        run.invoke(it,it.isFocused)
        if(it.isFocused){
            ActivityRun.onKeyBoardStatusChange{isOpen->
                if(!isOpen) run.invoke(it,false)
            }
        }
    }
}

// 辅助函数：将Compose的Rect转换为Android的Rect
private fun Rect.toAndroidRect(): android.graphics.Rect {
    return android.graphics.Rect(
        left.toInt(),
        top.toInt(),
        right.toInt(),
        bottom.toInt()
    )
}

/**
 * 修正版：监听当前界面的键盘收起事件
 * 解决currentScreenView定义错误的问题
 */
@Composable
fun CurrentScreenKeyboardListener(
    modifier: Modifier = Modifier,
    onKeyboardDismissed: () -> Unit
) {
    // 记录当前界面根布局的高度（dp）
    var rootHeight by remember { mutableStateOf(0.dp) }
    // 记录键盘是否可见
    var isKeyboardVisible by remember { mutableStateOf(false) }
    // 获取当前界面的根View（Compose视图的宿主View）
    val currentScreenView = LocalView.current // 关键：正确获取当前Compose视图
    // 密度转换工具
    val density = LocalDensity.current

    BoxWithConstraints(
        modifier = modifier
            // 监听当前界面根布局的尺寸变化，更新高度
            .onGloballyPositioned { coordinates ->
                rootHeight = with(density) { coordinates.size.height.toDp() }
            }
    ){
        this.maxHeight
        // 布局变化监听器（单独定义，避免赋值错误）
        val layoutListener = remember {
            ViewTreeObserver.OnGlobalLayoutListener {
                // 将dp转换为像素（用于计算）
                val rootHeightPx = with(density) { rootHeight.toPx() }.toInt()
                if (rootHeightPx == 0) return@OnGlobalLayoutListener // 避免初始状态错误

                // 获取当前可见区域（不含键盘的区域）
                val visibleRect = android.graphics.Rect()
                currentScreenView.getWindowVisibleDisplayFrame(visibleRect)
                val visibleHeight = visibleRect.height() // 可见区域高度

                // 键盘可见的判定：可见区域 < 界面高度的70%（可根据需求调整）
                val currentVisible = visibleHeight < rootHeightPx * 0.7f

                // 键盘从可见变为不可见时，触发收起回调
                if (isKeyboardVisible && !currentVisible) {
                    onKeyboardDismissed()
                }
                isKeyboardVisible = currentVisible
            }
        }
        // 注册和移除监听器（与当前界面生命周期绑定）
        DisposableEffect(currentScreenView) {
            // 注册监听器
            currentScreenView.viewTreeObserver.addOnGlobalLayoutListener(layoutListener)

            // 界面销毁时移除监听器（兼容低版本）
            onDispose {
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    currentScreenView.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
                } else {
                    @Suppress("DEPRECATION")
                    currentScreenView.viewTreeObserver.removeGlobalOnLayoutListener(layoutListener)
                }
            }
        }

    }
}


/**
 * remember持久化状态（自动保存和恢复）
 * @param key 存储键
 * @param defaultValue 默认值
 * @return 可观察的状态，修改时自动持久化
 */
@Composable
fun <T>  rememberMutableUserStateOf (
    key: String,
    defaultValue: T,
): MutableState<T> {
    // 创建内存状态
    val state = remember { mutableStateOf(defaultValue) }
    val scope = rememberCoroutineScope()

    // 初始化：从DataStore读取数据并更新内存状态
    remember(key) {
        scope.launch {
            val savedValue = UserStatus.get(key,defaultValue)
            state.value = savedValue
        }
    }

    // 监听状态变化：当值改变时自动保存到DataStore
    remember(state.value) {
        scope.launch {
            UserStatus.set(key,state.value)
        }
    }

    return state
}
